/**
 * @file mifare1oper.c
 * @author Victor Lau (1345236485@qq.com)
 * @brief 
 * @version 0.1
 * @date 2023-01-11
 * 
 * @copyright Copyright (c) 2023 Victor Lau. All rights reserved.
 * 
 */
#include "mifare1.h"
#include "iso14443.h"
#include "sky1311_drv.h"
#include "sky1311.h"
#include "bsp_modbus.h"

/***************************************************************
    M1卡�?�取扇区操作示例 1K�??
   读取扇区数据并通过串口打印出来
   寻卡等操作时，显示操作结�??
   有错�??时显示错�??信息
****************************************************************/
sta_result_t mifare1K_ReadTest(uint8_t *UID/*, uint32_t *work_num*/)
{
    sta_result_t sta;
    uint8_t tmpBuf[20];
    uint8_t default_key[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
    uint8_t i,j, sector_num=0, block_num=0;
    // uint16_t index = 0;

#if SKY_DEBUG==1
    printf("\n----Read Mifare1 test----\n");
#endif

    block_num = 0;
#if RFID_READ_ALL_SECTOR
    /* read test Mifare 1K card (0--63 block) */
    for(sector_num=0;sector_num<16;sector_num++)// read sector0--16
    {
        sta = M1_Authentication(M1_AUTH_KEYA, default_key , UID, block_num);
        if(Ok == sta)
        {
            /*  read 4 block from 1 sector */
            for( i=0;i<4;i++)
            {
                sta = M1_Read(block_num+i, tmpBuf);
                if(sta==Ok)
                {
                    #if SKY_DEBUG==1
                    printf("Block %02X : ",block_num+i);
                    for(j=0;j<16;j++)
                    {
                        printf("%02X ",tmpBuf[j]);
                        // usRegHoldingBuf[index] = tmpBuf[j];
                        // index++;
                    }
                    printf("\n");
                    #endif
                }
                else
                {
                    #if SKY_DEBUG==1
                    printf("Block %02X read error!\n",block_num+i);
                    #endif

                }
            }
            sky1311WriteReg(ADDR_M1_CTRL, 0x81);    // next Authentication
        }
        else
        {
            #if SKY_DEBUG==1
            printf("Sector %02X authentication error!\n",sector_num);
            #endif
            piccHaltA();
            sky1311WriteCmd(CMD_SW_RST);
            delay_ms(1);
            /*****************************************/
            sky1311WriteReg(ADDR_TIME_OUT2, 0x8F);       // time_out timer stop condition = beginning of RX SOF
            sky1311WriteReg(ADDR_TIME_OUT1, 0xFF);
            sky1311WriteReg(ADDR_TIME_OUT0, 0xFF);
            sky1311WriteReg(ADDR_RX_PUL_DETA, 0x34);     // �??4位识�??曼彻�??特码脉�?�，越大容错能力越强
            sky1311WriteReg(ADDR_RX_PRE_PROC, 0x00);
            sky1311WriteReg(ADDR_IRQ_EN, IRQ_M1_EN|IRQ_TOUT_EN|IRQ_TX_EN|IRQ_RX_EN|IRQ_HIGH_EN|IRQ_LOW_EN);    // enable all IRQ
            /*****************************************/
            sta = piccWakeupA(tmpBuf);
            if(sta != Ok)
                return sta;
            sta = piccSelectA(SEL1,UID,tmpBuf);
            if(sta != Ok)
                return sta;
        }
        #if SKY_DEBUG==1
        printf("\n");
        #endif
        block_num+=4;
    }
#else
    sta = M1_Authentication(M1_AUTH_KEYA, default_key , UID, block_num);
    if(Ok == sta)
    {
        /*  read 4 block from 1 sector */
        sta = M1_Read(block_num, tmpBuf);
        if(sta==Ok)
        {
            #if SKY_DEBUG==1
            for(j = 0; j < 16; j++)
                printf("%02X ",tmpBuf[j]);
            printf("\n");
            #endif
            // 四字节卡号
            usRegHoldingBuf[0] = tmpBuf[2] << 8 | tmpBuf[3];
            usRegHoldingBuf[1] = tmpBuf[0] << 8 | tmpBuf[1];
            // BCC + SAK
            usRegHoldingBuf[2] = tmpBuf[5] << 8 | tmpBuf[4];
            // ATQA
            usRegHoldingBuf[3] = tmpBuf[7] << 8 | tmpBuf[6];
            // 厂商信息
            usRegHoldingBuf[4] = tmpBuf[14] << 8 | tmpBuf[15];
            usRegHoldingBuf[5] = tmpBuf[12] << 8 | tmpBuf[13];
            usRegHoldingBuf[6] = tmpBuf[10] << 8 | tmpBuf[11];
            usRegHoldingBuf[7] = tmpBuf[8] << 8 | tmpBuf[9];
        }
        else
        {
            #if SKY_DEBUG==1
            printf("Block %02X read error!\n",block_num+i);
            #endif

        }

        sky1311WriteReg(ADDR_M1_CTRL, 0x81);    // next Authentication
    }
    else
    {
        #if SKY_DEBUG==1
        printf("Sector %02X authentication error!\n",sector_num);
        #endif
        piccHaltA();
        sky1311WriteCmd(CMD_SW_RST);
        delay_ms(1);
        /*****************************************/
        sky1311WriteReg(ADDR_TIME_OUT2, 0x8F);       // time_out timer stop condition = beginning of RX SOF
        sky1311WriteReg(ADDR_TIME_OUT1, 0xFF);
        sky1311WriteReg(ADDR_TIME_OUT0, 0xFF);
        sky1311WriteReg(ADDR_RX_PUL_DETA, 0x34);     // �??4位识�??曼彻�??特码脉�?�，越大容错能力越强
        sky1311WriteReg(ADDR_RX_PRE_PROC, 0x00);
        sky1311WriteReg(ADDR_IRQ_EN, IRQ_M1_EN|IRQ_TOUT_EN|IRQ_TX_EN|IRQ_RX_EN|IRQ_HIGH_EN|IRQ_LOW_EN);    // enable all IRQ
        /*****************************************/
        sta = piccWakeupA(tmpBuf);
        if(sta != Ok)
            return sta;
        sta = piccSelectA(SEL1,UID,tmpBuf);
        if(sta != Ok)
            return sta;
    }
    #if SKY_DEBUG==1
    printf("\n");
    #endif
#endif

    return Ok;
}
sta_result_t mifare_IncDecRestor_Test(uint8_t *UID)
{
    sta_result_t sta;
    uint8_t default_key[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
    uint8_t i, dat[16];
    int32_t i32data;
    i32data = 100000;
    dat[0] = (uint8_t)(i32data&0xff);
    dat[1] = (uint8_t)((i32data>>8) & 0xff);
    dat[2] = (uint8_t)((i32data>>16) & 0xff);
    dat[3] = (uint8_t)((i32data>>24) & 0xff);
    dat[4] = ~dat[0];
    dat[5] = ~dat[1];
    dat[6] = ~dat[2];
    dat[7] = ~dat[3];
    dat[8] =  dat[0];
    dat[9] =  dat[1];
    dat[10]=  dat[2];
    dat[11]=  dat[3];
    dat[12]=   4;
    dat[13]=  ~4;
    dat[14] =  4;
    dat[15] = ~4;
    sta = M1_Authentication(M1_AUTH_KEYA, default_key , UID, 4);
    if(sta==Ok)
    {
        sta = M1_Write(4,dat);
        if(sta==Ok)
            sta = M1_Increment(4, 100);

        dat[12]=5;  dat[13] = ~5;
        dat[14]=5;  dat[15] = ~5;
        if(sta==Ok)
            sta = M1_Write(5,dat);
        if(sta==Ok)
            sta = M1_Decrement(5, 100);

        if(sta==Ok)
        {
            sta = M1_Read(4,dat);
            i32data = 0;
            for( i=3;i>0;i--)
            {
                i32data += dat[i];
                i32data <<=8;
            }
            i32data += dat[0];
        }
        if(sta == Ok)
        {
            sta = M1_Read(5,dat);
            i32data = 0;
            for( i=3;i>0;i--)
            {
                i32data += dat[i];
                i32data <<=8;
            }
            i32data += dat[0];
        }
        i32data = i32data;
    }
    return sta;
}
/***************************************************************
    M1卡�?�取扇区操作示例 4K�??
   读取扇区数据并通过串口打印出来
   寻卡等操作时，显示操作结�??
   有错�??时显示错�??信息
****************************************************************/
#if 0
sta_result_t mifare4K_ReadTest(uint8_t *UID)
{
    sta_result_t sta;
    uint8_t tmpBuf[20];
    uint8_t default_key[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
    uint8_t i,j, sector_num=0, block_num=0;

    #if SKY_DEBUG==1
    printf("\nRead Mifare1 test\n");
    #endif

    block_num=0;
    /* read test Mifare 1K card (0--63 block) */
    for(sector_num=0;sector_num<16;sector_num++)// read sector0--16
    {
        sta = M1_Authentication(M1_AUTH_KEYA, default_key , UID, block_num);
        if(Ok == sta)
        {
            /*  read 4 block from 1 sector */
            for( i=0;i<4;i++)
            {
                sta = M1_Read(block_num+i, tmpBuf);
                if(sta==Ok)
                {
                    #if SKY_DEBUG==1
                    printf("Block %02X : ",block_num+i);
                    for(j=0;j<16;j++)
                        printf("%2X ",tmpBuf[j]);
                    printf("\n");
                    #endif
                }
                else{
                    #if SKY_DEBUG==1
                    printf("Block %02X read error!\n",block_num+i);
                    #endif
                }
            }
            sky1311WriteReg(ADDR_M1_CTRL, 0x81);    // next Authentication
        }
        else
        {
            #if SKY_DEBUG==1
            printf("Sector %02X authentication error\n"，sector_num);
            #endif  
            piccHaltA();
            sky1311_write_cmd(CMD_SW_RST);
            DelayMS(1);
            /*****************************************/
            sky1311WriteReg(ADDR_TIME_OUT2, 0x8F);       // time_out timer stop condition = beginning of RX SOF
            sky1311WriteReg(ADDR_TIME_OUT1, 0xFF);
            sky1311WriteReg(ADDR_TIME_OUT0, 0xFF);
            sky1311WriteReg(ADDR_RX_PUL_DETA, 0x34);     // �??4位识�??曼彻�??特码脉�?�，越大容错能力越强
            sky1311WriteReg(ADDR_RX_PRE_PROC, 0x00);
            sky1311WriteReg(ADDR_IRQ_EN, IRQ_M1_EN|IRQ_TOUT_EN|IRQ_TX_EN|IRQ_RX_EN|IRQ_HIGH_EN|IRQ_LOW_EN);    // enable all IRQ
            /*****************************************/
            sta = piccWakeupA(tmpBuf);
            if(sta != Ok)
                return sta;
            sta = piccSelectA(SEL1,UID,tmpBuf);
            if(sta != Ok)
                return sta;
        }
#if SKY_DEBUG==1
        printf("\n");
#endif
        block_num+=4;
    }
#if 1
    block_num = 64;
    /* read test Mifare 4K card (64--127 block) */
    for(sector_num=16;sector_num<32;sector_num++)// read sector16--31  (block64--127 )
    //for(block_num=64;block_num<128;)
    {
        sta = M1_Authentication(M1_AUTH_KEYA, default_key, UID, block_num);
        if(Ok == sta)
        {
            for(uint8_t i=0;i<4;i++)    /* 4 blocks/sector */
            {
                sta = M1_Read(block_num+i, tmpBuf);
                if(sta==Ok)
                {
                    #if SKY_DEBUG==1
                    printf("Block %02X : ",block_num+i);
                    for(j=0;j<16;j++)
                        printf("%2X ",tmpBuf[j]);
                    printf("\n");
                    #endif
                }
                else
                {
                    printf("Block %02X read Error\n",block_num+i);
                }
            }
            sky1311WriteReg(ADDR_M1_CTRL, 0x81);    // next Authentication
        }
        else{
#if SKY_DEBUG==1
            printf("Sector %02X authentication error!\n",sector_num);
#endif
            piccHaltA();
            sky1311_write_cmd(CMD_SW_RST);
            DelayMS(1);
            /*****************************************/
            sky1311WriteReg(ADDR_TIME_OUT2, 0x8F);       // time_out timer stop condition = beginning of RX SOF
            sky1311WriteReg(ADDR_TIME_OUT1, 0xFF);
            sky1311WriteReg(ADDR_TIME_OUT0, 0xFF);
            sky1311WriteReg(ADDR_RX_PUL_DETA, 0x34);     // �??4位识�??曼彻�??特码脉�?�，越大容错能力越强
            sky1311WriteReg(ADDR_RX_PRE_PROC, 0x00);
            sky1311WriteReg(ADDR_IRQ_EN, IRQ_M1_EN|IRQ_TOUT_EN|IRQ_TX_EN|IRQ_RX_EN|IRQ_HIGH_EN|IRQ_LOW_EN);    // enable all IRQ
            /*****************************************/
            sta = piccWakeupA(tmpBuf);
            if(sta != Ok)
                return sta;
            sta = piccSelectA(SEL1,UID,tmpBuf);
            if(sta != Ok)
                return sta;
        }
#if SKY_DEBUG==1
        printf("\n");
#endif
        block_num+=4;
        //sky1311WriteReg(ADDR_M1_CTRL, 0x81);
    }

    block_num = 128;        // sector_num = 32, 32*4=128
    /* read test Mifare 4K card (128--255 block) */
    for(sector_num=32;sector_num<40;sector_num++)// read sector32--39  (block128--255 )
    //for(block_num=128;block_num<255;)
    {
        sta = M1_Authentication(M1_AUTH_KEYA, default_key, UID, block_num);
        if(Ok == sta)
        {
            for( i=0;i<16;i++)       /* 16 blocks/sector */
            {
                sta = M1_Read(block_num+i, tmpBuf);
                if(sta==Ok)
                {
                    #if SKY_DEBUG==1
                    printf("Block %02X : ",block_num+i);
                    for(j=0;j<16;j++)
                        printf("%2X ",tmpBuf[j]);
                    printf("\n");
                    #endif
                }
                else
                {
                    #if SKY_DEBUG==1
                    printf("Block %02X read error!\n",block_num+i);
                    #endif
                }
            }
            sky1311WriteReg(ADDR_M1_CTRL, 0x81);
        }
        else{
            #if SKY_DEBUG==1
            printf("Sector %02X authentication error\n"，sector_num);
            #endif  
            piccHaltA();
            sky1311_write_cmd(CMD_SW_RST);
            DelayMS(1);
            /*****************************************/
            sky1311WriteReg(ADDR_TIME_OUT2, 0x8F);       // time_out timer stop condition = beginning of RX SOF
            sky1311WriteReg(ADDR_TIME_OUT1, 0xFF);
            sky1311WriteReg(ADDR_TIME_OUT0, 0xFF);
            sky1311WriteReg(ADDR_RX_PUL_DETA, 0x34);     // �??4位识�??曼彻�??特码脉�?�，越大容错能力越强
            sky1311WriteReg(ADDR_RX_PRE_PROC, 0x00);
            sky1311WriteReg(ADDR_IRQ_EN, IRQ_M1_EN|IRQ_TOUT_EN|IRQ_TX_EN|IRQ_RX_EN|IRQ_HIGH_EN|IRQ_LOW_EN);    // enable all IRQ
            /*****************************************/
            sta = piccWakeupA(tmpBuf);
            if(sta != Ok)
                return sta;
            sta = piccSelectA(SEL1,UID,tmpBuf);
            if(sta != Ok)
                return sta;
        }
        #if SKY_DEBUG==1
        printf("\n");
        #endif
        block_num+=16;
    }
#endif
    return Ok;
}
#endif
/***************************************************************
    M1卡写入操作示�??
    M1卡写�??Block4 (Sector 1) 和Block8（Sector2）操作�?
   寻卡等操作时，显示操作结�??
   有错�??时显示错�??信息
****************************************************************/
sta_result_t mifare1_WriteTest(uint8_t *UID, uint8_t *data)
{
    sta_result_t sta;
    uint8_t default_key[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

    #if SKY_DEBUG==1
    printf("\nWrite Mifare1 test\n");
    #endif

    sta = M1_Authentication(M1_AUTH_KEYA, default_key, UID, 1);     // 最后一�?参数�?要操作的块地址，和block_num相等
    if(Ok==sta)
    {
//        sta = M1_PwdChange(11,keya,keyb);
        if(Ok == sta)
        {
            sky1311WriteReg(ADDR_M1_CTRL, 0x81);
        }
    }
    else
    {
        piccHaltA();
        sky1311WriteReg(ADDR_M1_CTRL, 0x00);
        return Error;

    }

    irq_sta = sky1311ReadReg(ADDR_M1_CTRL);

    uint8_t block_num = 1;                                          // 将工号写入块1  
    sta = M1_Write(block_num, data);
    #if SKY_DEBUG==1
    printf("Block write %02X",block_num);
    #endif
    if(Ok == sta)
    {
        #if SKY_DEBUG==1
        printf("Success!\n");
        #endif
    }
    else{
        #if SKY_DEBUG==1
        printf("Failed!\n");
        #endif
    }

    return Ok;
}
